from flask import Flask, render_template,request,url_for,redirect,flash
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from werkzeug.security import generate_password_hash, check_password_hash
import os,sys,requests,click
from xml.dom import minidom


app = Flask(__name__)

prefix = 'sqlite:///' if sys.platform.startswith('win') else 'sqlite:////'
app.config['SQLALCHEMY_DATABASE_URI'] = prefix + os.path.join(app.root_path, 'mybooks.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'dev'

db = SQLAlchemy(app)

class Book(db.Model): 
    id=db.Column(db.Integer, primary_key=True)
    ISBN = db.Column(db.String(16), unique=False, nullable=False) # 主键
    title = db.Column(db.String(60), nullable=False) # 标题
    pages = db.Column(db.Integer) # 页数
    author = db.Column(db.String(60))
    price = db.Column(db.String(10))
    publisher = db.Column(db.String(20))
    pubdate = db.Column(db.String(10))
    link = db.Column(db.String(100))

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True) # 主键
    name = db.Column(db.String(20))
    psw = db.Column(db.String(128))
    def set_password(self, psw): # 用来设置密码的方法，接受密码作为参数
        self.psw = generate_password_hash(psw)
    def validate_psw(self, psw): # 用于验证密码的方法，接受密码作为参数
        return check_password_hash(self.psw, psw)

class Conn(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    userid = db.Column(db.Integer)
    bookid = db.Column(db.Integer)

@app.cli.command() # 注册为命令
@click.option('--drop', is_flag=True, help='Create after drop.') # 设置选项
def initdb(drop):
    """Initialize the database."""
    if drop: # 判断是否输入了选项
        db.drop_all()
    db.create_all()
    click.echo('Initialized database.') 

def ISBNdata(isbn):
    url='http://api.douban.com/book/subject/isbn/'
    rep=requests.get(url+isbn)
    if rep.status_code==404:
        return None
    DOM=minidom.parseString(rep.text)
    data={i.getAttribute('name'):i.childNodes[0].data for i in DOM.getElementsByTagName('db:attribute')}
    data['pages']=int(data.get('pages',0))
    link=DOM.getElementsByTagName('link')[1].getAttribute('href')
    data['link']=link
    item=Book(ISBN=data['isbn13'],title=data['title'],pages=data.get('pages',0),author=data.get('author',''),price=data.get('price','0'),publisher=data.get('publisher',''),pubdate=data.get('pubdate',''),link=data['link'])
    return item

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method=='POST':
        isbn=request.form.get('ISBN')
        add(isbn)
    cnt=Book.query.count()
    user='Cherichy'
    books = Book.query.limit(10).all()
    return render_template('index.html', count=cnt,name=user, books=books)

@app.route('/page/<int:p>', methods=['GET', 'POST'])
def page(p):
    cnt=Book.query.count()
    user='Cherichy'
    books = Book.query.limit(10).offset(p*10).all()
    return render_template('index.html', count=cnt,name=user, books=books)


@app.route('/delete/<isbn>',methods=['POST'])
def delete(isbn):
    book=Book.query.get_or_404(isbn)
    db.session.delete(book)
    db.session.commit()
    flash('Item deleted!')
    return redirect(url_for('index'))

@app.route('/add/<isbn>',methods=['GET','POST'])
def add(isbn):
    isbn=isbn.strip()
    if Book.query.get(isbn) != None:
        flash('Item existed!')
        return redirect(url_for('index'))
    book=ISBNdata(isbn)
    if book == None:
        flash('Invalid ISBN!')
        return redirect(url_for('index'))
    else:
        db.session.add(book)
        db.session.commit()
        flash('Item added!')
        return redirect(url_for('index'))

@app.route('/backup')
def backup():
    with open('static/backup.txt','w') as f:
        for item in db.session.query(Book.ISBN).all():
            f.write(item[0]+'\n')
    flash('Backup finished!')
    return redirect(url_for('index'))
    

@app.route('/recover')
def recover():
    with open('static/backup.txt','r') as f:
        for isbn in f.readlines():
            isbn=isbn.strip()
            if Book.query.get(isbn) == None:
                book=ISBNdata(isbn)
                if book != None:
                    db.session.add(book)
        db.session.commit()
    flash('Recover finished!')
    return redirect(url_for('index'))